package frame

import (
	"fmt"
	"sync"
	"sync/atomic"

	"gitee.com/go-mao/mao/libs/try"
	"xorm.io/xorm"
)

type Taskline struct {
	server      *Server
	lock        *sync.Mutex
	engine      *xorm.Engine
	xormSession *xorm.Session
	startTrans  bool //开启了事务
	index       int64
	sessionId   string
}

// 创建一个任务线
func newTaskline(server *Server, engine *xorm.Engine) *Taskline {
	atomic.AddInt64(&server.taskIndex, 1)
	object := &Taskline{index: server.taskIndex, server: server}
	object.engine = engine
	return object
}

// 设置ORM数据库引擎，用于多数据库连接的时候
func (this *Taskline) UseEngine(engine *xorm.Engine) {
	this.engine = engine
}

// 获取当前taskline的id
func (this *Taskline) GetTaskid() int64 {
	return this.index
}

// 当前请求的互斥锁
func (this *Taskline) Mutex() *sync.Mutex {
	if this.lock == nil {
		this.lock = &sync.Mutex{}
	}
	return this.lock
}

// 放置钩子
func (this *Taskline) PutHook(h HookInterface) {
	this.server.hook.trigger(this, h)
}

// 实例化一个对象【泛型】
func (this *Taskline) OrmModel(model ModelInterface) ModelInterface {
	model.init(this.OrmSession(), model)
	return model
}

// 初始化数据库模型
func (this *Taskline) OrmTable(bean any) *xorm.Session {
	return this.OrmSession().Table(bean)
}

// ORM对象，
func (this *Taskline) OrmSession() *xorm.Session {
	if this.xormSession == nil {
		if this.engine != nil {
			this.xormSession = this.engine.NewSession()
		} else {
			this.xormSession = this.server.ormEngine.NewSession()
		}
	}
	return this.xormSession
}

// 新建一个任务线
func (this *Taskline) NewTaskLine() *Taskline {
	return newTaskline(this.server, this.engine)
}

// 开启事务，只执行最上面层的事务
func (this *Taskline) Transaction(fn func()) {
	if this.startTrans {
		fn()
		return
	}
	this.startTrans = true
	defer func() {
		this.startTrans = false
	}()
	sess := this.OrmSession()
	try.Do(func() {
		sess.Begin()
		fn()
		sess.Commit()
	}, func(e try.Exception) {
		sess.Rollback()
		try.Throw(e.ErrCode(), e.ErrMsg())
	})
}

// 分页查询
// listPtr	= 查询列表指针
// page	= 页码
// limit	= 每页查询数量
// 返回查询总数
func (this *Taskline) FindPage(db *xorm.Session, listPtr interface{}, page, limit int) int64 {
	if page <= 0 {
		page = 1
	}
	if limit == 0 {
		limit = 20
	}
	if limit > 1000 {
		limit = 1000
	}
	start := (page - 1) * limit
	total, err := db.Limit(limit, start).FindAndCount(listPtr)
	CheckSqlError(err)
	return total
}

// 获取配置对象
func (this *Taskline) MaoConfig() MaoConfigInterface {
	return this.server.config
}

// 初始化配置
func (this *Taskline) RenderConfig(conf ConfigInterface) ConfigInterface {
	return this.MaoConfig().Get(conf)
}

// 调试日志输出
func (this *Taskline) LogDebug(args ...any) {
	this.server.logger.Debug(append([]any{fmt.Sprintf("[%d]", this.index)}, args...)...)

}

// 调试日志输出，可格式化
func (this *Taskline) LogDebugf(format string, args ...any) {
	this.server.logger.Debugf(fmt.Sprintf("[%d]", this.index)+format, args...)
}

// 信息日志输出
func (this *Taskline) LogInfo(args ...any) {
	this.server.logger.Info(append([]any{fmt.Sprintf("[%d]", this.index)}, args...)...)

}

// 信息日志输出，可格式化
func (this *Taskline) LogInfof(format string, args ...any) {
	this.server.logger.Infof(fmt.Sprintf("[%d]", this.index)+format, args...)
}

// 警告日志输出
func (this *Taskline) LogWarn(args ...any) {
	this.server.logger.Warn(append([]any{fmt.Sprintf("[%d]", this.index)}, args...)...)
}

// 警告日志输出，可格式化
func (this *Taskline) LogWarnf(format string, args ...any) {
	this.server.logger.Warnf(fmt.Sprintf("[%d]", this.index)+format, args...)
}

// 错误日志输出
func (this *Taskline) LogError(args ...any) {
	this.server.logger.Error(append([]any{fmt.Sprintf("[%d]", this.index)}, args...)...)
}

// 错误日志输出，可格式化
func (this *Taskline) LogErrorf(format string, args ...any) {
	this.server.logger.Errorf(fmt.Sprintf("[%d]", this.index)+format, args...)
}
